﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Code.Models;
using Code.Commen;

namespace Code.BLL
{
    public class CardManage:ManageBase<Cards>
    {
        /// <summary>
        /// 添加点卡
        /// </summary>
        public int AddCard(double money, int count)
        {
            int rs = 0;
            if (count > 500)
                throw new ValidateException("一次最多生成500张", "count");

            var cards = BuildCard(count);
            var data = cards.Select(p => new { Number = p.Key, Password = EncryptPwd(p.Value), Money = money }).ToArray();
            base.BeginTransaction();
            base.Insert<Cards>(data);
            rs = base.ExecuteTransaction();

            return rs;
        }

        /// <summary>
        /// 点卡充值
        /// </summary>
        public int CardPay(string number, string password, Guid uid)
        {
            int rs = 0;
            if (string.IsNullOrEmpty(number))
                throw new ValidateException("卡号不能为空", "number");
            if (string.IsNullOrEmpty(password))
                throw new ValidateException("密码不能为空", "password");
            if (!CacheManage.OptionSite[Option_Site_Key.Site_CardPay_Enable].ToBool(false))
                throw new ValidateException("点卡充值已关闭！","Error");

            number = number.ToUpper();
            password = EncryptPwd(password);
            var card = base.Tables.Cards.FirstOrDefault(p => p.Number == number);
            if (card == null || card.Password != password)
                throw new ValidateException("卡号或密码不正确", "Error");
            if (card.State != (short)CardState.Normal)
                throw new ValidateException("该点卡" + ((CardState)card.State).GetName(), "Error");

            base.BeginTransaction();
            base.Update<Cards>(new { State = CardState.Used, UserID = uid, UseTime = DateTime.Now }, new { Number = number, State = CardState.Normal });
            base.Insert<AddMoneyDetail>(new { UserID = uid, Money = card.Money, Type = (short)AddMoneyType.CardPay, RefID = new Guid(number), Remark = "卡号:" + number });
            base.Update<Account>(new { Balance = new OpteratorValue(Opterator.Add, card.Money), AddMoney = new OpteratorValue(Opterator.Add, card.Money) }, new { UserID = uid });
            rs = base.ExecuteTransaction(3);
            return rs;
        }

        /// <summary>
        /// 删除点卡
        /// </summary>
        public int Del(IEnumerable<string> numbers)
        {
            return base.Delete<Cards>(new { State = (short)CardState.Normal, Number = new ComparValue(Comparison.In, numbers) });
        }
        
        /// <summary>
        /// 生成点卡
        /// </summary>
        public IDictionary<string,string> BuildCard(int count)
        {
            var rs = new Dictionary<string, string>();
            if (count <= 0)
                throw new ValidateException("数量不正确", "count");
            
            var r=new Random();
            for (int i = 0; i < count; i++)
            {
                var num = Guid.NewGuid().ToString("N").ToUpper();
                var pwd = r.Next(102340, 997987).ToString();
                rs.Add(num, pwd);
            }

            return rs;
        }

        public IEnumerable<CardItem> FindCard(CardSearchModel search)
        {
            var data = base.Select(s => s.OrderBy("AddTime DESC,Number ASC")
                .Select(p => new CardItem { Number = p.Number, Password = p.Password, Money = (double)p.Money, State = (CardState)p.State, AddTime = p.AddTime, UseTime = p.UseTime, UserID = p.UserID, UserName = p.Users.LoginName, Remark = p.Remark }));
            if (search == null)
                return data;
            if (!string.IsNullOrEmpty(search.Number))
                data = data.Where(p => p.Number == search.Number.Trim().ToUpper());
            if (!string.IsNullOrEmpty(search.UserName))
                data = data.Where(p => p.UserName == search.UserName.Trim());
            if (search.State.HasValue)
                data = data.Where(p => p.State == search.State);
            if (search.Money.HasValue)
                data = data.Where(p => p.Money == search.Money);
            if (search.AddStartTime.HasValue)
                data = data.Where(p => p.AddTime >= search.AddStartTime);
            if (search.AddEndTime.HasValue)
                data = data.Where(p => p.AddTime < search.AddEndTime.Value.AddDays(1));
            if (search.UseStartTime.HasValue)
                data = data.Where(p => p.UseTime >= search.UseStartTime);
            if (search.UseEndTime.HasValue)
                data = data.Where(p => p.UseTime < search.UseEndTime.Value.AddDays(1));
            return data;
        }

        /// <summary>
        /// 加密点卡密码
        /// </summary>
        /// <param name="pwd"></param>
        /// <returns></returns>
        public static string EncryptPwd(string pwd)
        {
            return des.EncryptString(pwd);
        }
        /// <summary>
        /// 解密点卡密码
        /// </summary>
        /// <param name="pwd"></param>
        /// <returns></returns>
        public static string DecryptPwd(string pwd)
        {
            try { return des.DecryptString(pwd); }
            catch { return "解密失败"; }
        }


        private static DES _des;
        private static DES des
        {
            get {
                if (_des == null)
                {
                    var salt = Salt.Password.GetDesSalt();
                    _des = new DES(salt.Key, salt.Value);
                }
                return _des;
            }
        }
        
        public class CardItem
        {
            public string Number { get; set; }
            public string Password { get; set; }
            public double Money { get; set; }
            public CardState State { get; set; }
            public DateTime AddTime { get; set; }
            public DateTime? UseTime { get; set; }
            public Guid? UserID { get; set; }
            public string UserName { get; set; }
            public string Remark { get; set; }
        }

    public class CardSearchModel
    {
        public virtual string Number { get; set; }
        public virtual string UserName { get; set; }
        public virtual double? Money { get; set; }
        public virtual CardState? State { get; set; }
        public virtual DateTime? AddStartTime { get; set; }
        public virtual DateTime? AddEndTime { get; set; }
        public virtual DateTime? UseStartTime { get; set; }
        public virtual DateTime? UseEndTime { get; set; }
    }   

    }
}
